home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xmlink / xmlink.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  11KB  |  375 lines

  1. /*
  2. # X-BASED MISSING LINK(tm)
  3. #
  4. #  xmlink.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 1: 94/08/30 Xt
  28. */
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #ifdef VMS
  33. #include <unixlib.h>
  34. #define getlogin cuserid
  35. #else
  36. #ifndef apollo
  37. #include <unistd.h>
  38. #endif
  39. #endif
  40. #include <X11/Intrinsic.h>
  41. #include <X11/StringDefs.h>
  42. #include <X11/Shell.h>
  43. #include <X11/cursorfont.h>
  44. #include "Mlink.h"
  45. #include "mlink.xbm"
  46.  
  47. #ifndef SCOREFILE
  48. #define SCOREFILE "/usr/games/lib/mlink.scores"
  49. #endif
  50.  
  51. /* The following are in MlinksP.h also */
  52. #define MINFACES 1
  53. #define MAXFACES 8
  54. #define MINTILES 1
  55.  
  56. #define MAXTILES 8
  57. #define MAXRECORD 32767
  58. #define MAXPROGNAME 80
  59. #define MAXNAME 256
  60.  
  61. static void Initialize();
  62. static void CallbackMlink();
  63.  
  64. static void PrintRecord();
  65. static int HandleSolved();
  66. static void PrintState();
  67. static void ReadRecords();
  68. static void WriteRecords();
  69.  
  70. static Arg arg[1];
  71. static int mlinkRecord[2][2][MAXFACES - MINFACES + 1][MAXTILES - MINTILES + 1];
  72. static int movesDsp = 0;
  73. static char progDsp[64] = "xmlink";
  74. static char recordDsp[16] = "INF";
  75. static char messageDsp[128] = "Welcome";
  76. static char titleDsp[256] = "";
  77.  
  78. static void Usage()
  79. {
  80.   (void) fprintf(stderr, "usage: xmlink\n");
  81.   (void) fprintf(stderr,
  82.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  83.   (void) fprintf(stderr,
  84.     "\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
  85.   (void) fprintf(stderr,
  86.     "\t[-mono] [-tile {color}] [-{border|bd} {color}]\n");
  87.   (void) fprintf(stderr,
  88.     "\t[-tiles {int}] [-faces {int}] [-[no]orient] [-[no]middle]\n");
  89.   (void) fprintf(stderr,
  90.     "\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
  91.   exit(1);
  92. }
  93.  
  94. static XrmOptionDescRec options[] = {
  95.   {"-fg",        "*mlink.Foreground",    XrmoptionSepArg,    NULL},
  96.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  97.   {"-foreground",    "*mlink.Foreground",    XrmoptionSepArg,    NULL},
  98.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  99.   {"-tile",        "*mlink.tileColor",    XrmoptionSepArg,    NULL},
  100.   {"-border",        "*mlink.tileBorder",    XrmoptionSepArg,    NULL},
  101.   {"-bd",        "*mlink.tileBorder",    XrmoptionSepArg,    NULL},
  102.   {"-tiles",        "*mlink.tiles",        XrmoptionSepArg,    NULL},
  103.   {"-faces",        "*mlink.faces",        XrmoptionSepArg,    NULL},
  104.   {"-orient",        "*mlink.orient",    XrmoptionNoArg,        "TRUE"},
  105.   {"-noorient",        "*mlink.orient",    XrmoptionNoArg,        "FALSE"},
  106.   {"-middle",        "*mlink.middle",    XrmoptionNoArg,        "TRUE"},
  107.   {"-nomiddle",        "*mlink.middle",    XrmoptionNoArg,        "FALSE"},
  108.   {"-mono",        "*mlink.mono",        XrmoptionNoArg,        "TRUE"},
  109.   {"-face0",        "*mlink.faceColor0",    XrmoptionSepArg,    NULL},
  110.   {"-face1",        "*mlink.faceColor1",    XrmoptionSepArg,    NULL},
  111.   {"-face2",        "*mlink.faceColor2",    XrmoptionSepArg,    NULL},
  112.   {"-face3",        "*mlink.faceColor3",    XrmoptionSepArg,    NULL},
  113.   {"-face4",        "*mlink.faceColor4",    XrmoptionSepArg,    NULL},
  114.   {"-face5",        "*mlink.faceColor5",    XrmoptionSepArg,    NULL},
  115.   {"-face6",        "*mlink.faceColor6",    XrmoptionSepArg,    NULL},
  116.   {"-face7",        "*mlink.faceColor7",    XrmoptionSepArg,    NULL}
  117. };
  118.  
  119. int main(argc, argv)
  120.   int argc;
  121.   char *argv[];
  122. {
  123.   Widget toplevel, mlink; 
  124.  
  125.   toplevel = XtInitialize(argv[0], "Mlink",
  126.     options, XtNumber(options), &argc, argv);
  127.   if (argc != 1)
  128.     Usage();
  129.  
  130.   XtSetArg(arg[0], XtNiconPixmap,
  131.     XCreateBitmapFromData(XtDisplay(toplevel),
  132.       RootWindowOfScreen(XtScreen(toplevel)),
  133.       (char *) mlink_bits, mlink_width, mlink_height));
  134.   XtSetValues(toplevel, arg, 1);
  135.   mlink = XtCreateManagedWidget("mlink", mlinkWidgetClass, toplevel,
  136.     NULL, 0);
  137.   XtAddCallback(mlink, XtNselectCallback, CallbackMlink, NULL);
  138.   Initialize(mlink);
  139.   XtRealizeWidget(toplevel);
  140.   XGrabButton(XtDisplay(mlink), AnyButton, AnyModifier, XtWindow(mlink),
  141.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  142.     GrabModeAsync, GrabModeAsync, XtWindow(mlink),
  143.     XCreateFontCursor(XtDisplay(mlink), XC_crosshair));
  144.   XtMainLoop();
  145.  
  146. #ifdef VMS
  147.   return 1;
  148. #else
  149.   return 0;
  150. #endif
  151. }
  152.  
  153. static void Initialize(w)
  154.   Widget w;
  155. {
  156.   int tiles, faces;
  157.   Boolean orient, middle;
  158.  
  159.   XtVaSetValues(w,
  160.     XtNstart, FALSE,
  161.     NULL);
  162.   XtVaGetValues(w,
  163.     XtNtiles, &tiles,
  164.     XtNfaces, &faces,
  165.     XtNorient, &orient,
  166.     XtNmiddle, &middle,
  167.     NULL);
  168.   ReadRecords();
  169.   PrintRecord(tiles, faces, orient, middle, recordDsp);
  170.   PrintState(XtParent(w), progDsp, tiles, faces, middle, movesDsp,
  171.     recordDsp, messageDsp);
  172. }
  173.  
  174. static void CallbackMlink(w, clientData, callData)
  175.   Widget w;
  176.   caddr_t clientData;
  177.   mlinkCallbackStruct *callData;
  178. {
  179.   int tiles, faces;
  180.   Boolean orient, middle;
  181.  
  182.   XtVaGetValues(w,
  183.     XtNtiles, &tiles,
  184.     XtNfaces, &faces,
  185.     XtNorient, &orient,
  186.     XtNmiddle, &middle,
  187.     NULL);
  188.   (void) strcpy(messageDsp, "");
  189.   switch (callData->reason) {
  190.     case MLINK_RESTORE:
  191.     case MLINK_RESET:
  192.       movesDsp = 0;
  193.       break;
  194.     case MLINK_BLOCKED:
  195.       (void) strcpy(messageDsp, "Blocked");
  196.       break;
  197.     case MLINK_SPACE:
  198.       /*(void) strcpy(messageDsp, "Spaces can't move");*/  /* Too annoying */
  199.       break;
  200.     case MLINK_IGNORE:
  201.       (void) strcpy(messageDsp, "Randomize to start");
  202.       break;
  203.     case MLINK_MOVED:
  204.       movesDsp++;
  205.       XtSetArg(arg[0], XtNstart, TRUE);
  206.       XtSetValues(w, arg, 1);
  207.       break;
  208.     case MLINK_CONTROL:
  209.       return;
  210.     case MLINK_SOLVED:
  211.       if (HandleSolved(movesDsp, tiles, faces, orient, middle))
  212.         (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  213.       else
  214.         (void) strcpy(messageDsp, "Solved!");
  215.       XtSetArg(arg[0], XtNstart, FALSE);
  216.       XtSetValues(w, arg, 1);
  217.       break;
  218.     case MLINK_RANDOMIZE:
  219.       movesDsp = 0;
  220.       XtSetArg(arg[0], XtNstart, FALSE);
  221.       XtSetValues(w, arg, 1);
  222.       break;
  223.     case MLINK_ORIENT:
  224.       movesDsp = 0;
  225.       orient = !orient;
  226.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  227.       XtSetArg(arg[0], XtNorient, orient);
  228.       XtSetValues(w, arg, 1);
  229.       break;
  230.     case MLINK_MIDDLE:
  231.       movesDsp = 0;
  232.       middle = !middle;
  233.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  234.       XtSetArg(arg[0], XtNmiddle, middle);
  235.       XtSetValues(w, arg, 1);
  236.       break;
  237.     case MLINK_DEC_X:
  238.       movesDsp = 0;
  239.       tiles--;
  240.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  241.       XtSetArg(arg[0], XtNtiles, tiles);
  242.       XtSetValues(w, arg, 1);
  243.       break;
  244.     case MLINK_INC_X:
  245.       movesDsp = 0;
  246.       tiles++;
  247.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  248.       XtSetArg(arg[0], XtNtiles, tiles);
  249.       XtSetValues(w, arg, 1);
  250.       break;
  251.     case MLINK_DEC_Y:
  252.       movesDsp = 0;
  253.       faces--;
  254.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  255.       XtSetArg(arg[0], XtNfaces, faces);
  256.       XtSetValues(w, arg, 1);
  257.       break;
  258.     case MLINK_INC_Y:
  259.       movesDsp = 0;
  260.       faces++;
  261.       PrintRecord(tiles, faces, orient, middle, recordDsp);
  262.       XtSetArg(arg[0], XtNfaces, faces);
  263.       XtSetValues(w, arg, 1);
  264.       break;
  265.     case MLINK_COMPUTED:
  266.       XtSetArg(arg[0], XtNstart, FALSE);
  267.       XtSetValues(w, arg, 1);
  268.       break;
  269.     case MLINK_UNDO:
  270.       movesDsp--;
  271.       XtSetArg(arg[0], XtNstart, TRUE);
  272.       XtSetValues(w, arg, 1);
  273.       break;
  274.   }
  275.   PrintState(XtParent(w), progDsp, tiles, faces, middle, movesDsp,
  276.     recordDsp, messageDsp);
  277. }
  278.  
  279. static void PrintRecord(tiles, faces, orient, middle, record)
  280.   int tiles, faces;
  281.   Boolean orient, middle;
  282.   char *record;
  283. {
  284.   int i = tiles - MINTILES, j = faces - MINFACES;
  285.   int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
  286.  
  287.   if (tiles > MAXTILES)
  288.     (void) strcpy(record, "NOT RECORDED");
  289.   else if (mlinkRecord[l][k][j][i] >= MAXRECORD)
  290.     (void) strcpy(record, "NEVER");
  291.   else
  292.     (void) sprintf(record, "%d", mlinkRecord[l][k][j][i]);
  293. }
  294.  
  295. static int HandleSolved(counter, tiles, faces, orient, middle)
  296.   int counter, tiles, faces;
  297.   Boolean orient, middle;
  298. {
  299.   int i = tiles - MINTILES, j = faces - MINFACES;
  300.   int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
  301.  
  302.   if (tiles <= MAXTILES && counter < mlinkRecord[l][k][j][i]) {
  303.     mlinkRecord[l][k][j][i] = counter;
  304.     if (tiles < 4 || faces < 2)
  305.       mlinkRecord[!l][k][j][i] = counter;
  306.     WriteRecords();
  307.     (void) sprintf(recordDsp, "%d", counter);
  308.     return TRUE;
  309.   }
  310.   return FALSE;
  311. }
  312.  
  313. static void PrintState(w, prog, tiles, faces, middle, moves, record, message)
  314.   Widget w;
  315.   char *prog, *record, *message;
  316.   int tiles, faces, moves;
  317.   Boolean middle;
  318. {
  319.   if (middle)
  320.     (void) sprintf(titleDsp, "%s: %dx%d norm@ (%d/%s) - %s",
  321.              prog, tiles, faces, moves, record, message);
  322.   else
  323.     (void) sprintf(titleDsp, "%s: %dx%d ind@ (%d/%s) - %s",
  324.              prog, tiles, faces, moves, record, message);
  325.   XtSetArg(arg[0], XtNtitle, titleDsp);
  326.   XtSetValues(w, arg, 1);
  327. }
  328.  
  329. static void ReadRecords()
  330. {
  331.   FILE *fp;
  332.   int i, j, k, l, n;
  333.  
  334.   for (l = 0; l < 2; l++)
  335.     for (k = 0; k < 2; k++)
  336.       for (j = 0; j < MAXFACES - MINFACES + 1; j++)
  337.         for (i = 0; i < MAXTILES - MINTILES + 1; i++)
  338.           mlinkRecord[l][k][j][i] = MAXRECORD;
  339.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  340.     (void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
  341.   else {
  342.     for (l = 0; l < 2; l++)
  343.       for (k = 0; k < 2; k++)
  344.         for (j = 0; j < MAXFACES - MINFACES + 1; j++)
  345.           for (i = 0; i < MAXTILES - MINTILES + 1; i++) {
  346.             (void) fscanf(fp, "%d", &n);
  347.             mlinkRecord[l][k][j][i] = n;
  348.       }
  349.     (void) fclose(fp);
  350.   }
  351. }
  352.  
  353. static void WriteRecords()
  354. {
  355.   FILE *fp;
  356.   int i, j, k, l;
  357.  
  358.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  359.     (void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
  360.   else {
  361.     for (l = 0; l < 2; l++) {
  362.       for (k = 0; k < 2; k++) {
  363.         for (j = 0; j < MAXFACES - MINFACES + 1; j++) {
  364.           for (i = 0; i < MAXTILES - MINTILES + 1; i++)
  365.             (void) fprintf(fp, "%d ", mlinkRecord[l][k][j][i]);
  366.           (void) fprintf(fp, "\n");
  367.         }
  368.         (void) fprintf(fp, "\n");
  369.       }
  370.       (void) fprintf(fp, "\n");
  371.     }
  372.     (void) fclose(fp);
  373.   }
  374. }
  375.